import gi
gi.require_version('Nautilus', '3.0')

from gi.repository import Nautilus, GObject

import os, time, json
try:
    from urllib import unquote
except ImportError:
    from urllib.parse import unquote

# install python3-nautilus
# store at: ~/.local/share/nautilus-python/extensions

class UserDefMenuProvider(GObject.GObject, Nautilus.MenuProvider):
    def __init__(self):
        pass

    def get_file_items(self, window, files):
        #self.msg('start get_file_items')
        if len(files) != 1:
            return None
        cfg = self.load_config()
        if cfg == None:
            #self.msg('error load config')
            return None
        idx = 0
        for name in files:
            uri1 = name.get_uri()
            filename = unquote(uri1[7:])
            ret = self.append_file_menuitem(filename, cfg, idx)
            #self.msg('append %s'%( str(ret) ))
            if len(ret) > 0:
                #self.msg( 'get_file_items return %s'%( str(ret) ) )
                return ret
            idx += 1
        #self.msg('get_file_items return None')
        return None

    def load_config(self):
        #return like: "[{'ext': '.zip', 'prog': 'unzip-go', 'args': [], 'label': '用unzip-go解压缩'}, {'ext': '.zip', 'prog': 'unzip', 'args': ['-O', 'CP936'], 'label': '解压缩windows中文压缩包'}]"
        try:
            home = os.getenv('HOME')
            cfg = os.path.join(home, '.nautilus-user-actions/config.json')
            fp = open(cfg)
            res = json.load(fp)
            fp.close()
            return res
        except:
            pass
        return None

    def userdef_activate_cb(self, menu, v):
        # v = {'prog':'prog', 'args':args, 'file':filename, 'ext':ext}
        try:
            argv = []
            argv.append(v['prog'])
            for i in range(len(v['args'])):
                item = str(v['args'][i]).replace('$F', v['file'])
                item = item.replace('$D',os.path.dirname(v['file']))
                item = item.replace( '$N', str(v['file'])[:0-len(v['ext'])] )
                argv.append( item )
            os.chdir(os.path.dirname(v['file']))
            self.msg( '%s %s %s'%(time.ctime(), v['prog'], str(argv)) )
            os.spawnvp( os.P_WAIT, v['prog'], argv )
        except:
            pass
        return

    def append_file_menuitem(self, filename, cfg, idx):
        res = []
        n = 0
        for item in cfg:
            #self.msg(str(item)+' '+filename)
            if filename.lower().endswith(item['ext'].lower()) == False:
                continue
            item_name = 'UserDefMenuProvider::UserDef%dn%d'%(idx, n)
            menuitem = Nautilus.MenuItem(name = item_name, 
                                         label = item['label'], 
                                         tip = '', 
                                         icon = '', 
                                         )
            argv = {'prog':item['prog'], 'args':item['args'], 'file':filename, 'ext':item['ext']}
            menuitem.connect("activate", self.userdef_activate_cb, argv)
            res.append(menuitem)
            n += 1
        return res

    def msg(self, s):
        fp = open('/tmp/msg.txt', mode = 'a')
        fp.write(time.ctime()+' '+s+'\n')
        fp.close()
